<?php

namespace App\Exceptions;

use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Support\Facades\Log;
use Illuminate\Validation\ValidationException;
use ruoyi\admin\constant\HttpStatus;
use Throwable;

class Handler extends ExceptionHandler
{
    /**
     * A list of exception types with their corresponding custom log levels.
     *
     * @var array<class-string<\Throwable>, \Psr\Log\LogLevel::*>
     */
    protected $levels = [
        //
    ];

    /**
     * A list of the exception types that are not reported.
     *
     * @var array<int, class-string<\Throwable>>
     */
    protected $dontReport = [
        ValidationException::class,
        ApiException::class,
    ];

    /**
     * A list of the inputs that are never flashed to the session on validation exceptions.
     *
     * @var array<int, string>
     */
    protected $dontFlash = [
        'current_password',
        'password',
        'password_confirmation',
    ];

    /**
     * Register the exception handling callbacks for the application.
     *
     * @return void
     */
    public function register()
    {
        $this->reportable(function (Throwable $e) {
            //
        });
    }

    /**
     * Render an exception into an HTTP response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Throwable  $e
     * @return \Symfony\Component\HttpFoundation\Response
     *
     * @throws \Throwable
     */
    public function render($request, Throwable $e) {
        Log::error($e);
        if ($e instanceof ValidationException) {
            return response()->json(['code'=>HttpStatus::BAD_REQUEST, 'msg'=>$e->validator->errors()->first()]);
        } else if ($e instanceof ApiException) {
            return show_response(null, $e->getMessage(), 400);
        } else if ($e instanceof \Illuminate\Auth\AuthenticationException) {
            $msg = request()->hasHeader('authorization') ? '令牌已过期, 请重新登录 !' : '用户未登录 !';
            return show_response(msg:$msg, code:410);
        }
        return parent::render($request, $e);
    }

    public function report(Throwable $e) {
        if (config('app.debug')) return;
        if (collect($this->dontReport)->filter(fn($it)=>$e instanceof $it)->isNotEmpty()) return;
        $this->notifyWx($e);
    }


    private function notifyWx($e) {
        // 企业微信中创建一个群(xx后台管理系统-异常通知群), 新增一个机器人
        // 机器人key
        $bot_key = 'fe6a1426-ea8a-4609-b74a-ddb367d085c5';
        // >message:<font color=\"comment\">{$e->getMessage()}</font>
        try {
            $trace = strlen($e->getTraceAsString()) > 3000 ? substr($e->getTraceAsString(), 0, 3000) : $e->getTraceAsString();
            $clazz = str_replace("\\", "/", get_class($e));
            $curl = <<<EOF
                curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={$bot_key}' \
                -H 'Content-Type: application/json' \
                -d '
                {
                        "msgtype": "markdown",
                        "markdown": {
                            "content": "
                            ```
                $trace
                            ```
                            >code:<font color=\"comment\">{$e->getCode()}</font>
                            >file:<font color=\"comment\">{$e->getFile()}</font>
                            >line:<font color=\"comment\">{$e->getLine()}</font>
                            >clazz:<font color=\"comment\">{$clazz}</font>"
                        }
                    }'
            EOF;
            $res = exec($curl);
            // dump($res);
        } catch(\Exception $e) { Log::error($e); }
    }

}
